﻿using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NDBGen.Configuration;
using NDBGen.Plugins;

namespace NDBGen.Tests
{
    [TestClass]
    public class SqlServerScriptGeneratorTests : DatabaseGeneratorUnitTestBase<SqlServerScriptGenerator>
    {
        [TestInitialize]
        public override void TestInitialize()
        {
            base.TestInitialize();
        }

        [TestMethod]
        public void TestComposition()
        {
            var catalog = new AssemblyCatalog(typeof(SqlServerScriptGenerator).Assembly);
            using (var container = new CompositionContainer(catalog))
            {
                var tester = new CompositionTester<IColumnDataTypeScriptSnippetGenerator, IGeneratorMetadata>();
                container.ComposeParts(tester);

                Assert.IsNotNull(tester.Imports);
                Assert.IsTrue(tester.Imports.Any());
            }
        }

        [TestMethod]
        public void GenerateSqlForSingleSchemaSingleTable()
        {
            ParsedInput parsedInput;
            var generator = this.GetGenerator(out parsedInput, SampleSchema.SingleSchemaSingleTable);

            var actual = Database.GenerateSchemaScripts(SchemaOutputType.Create, null, parsedInput, generator);
            var expected = ExpectedResults.MarkupSingleSchemaSingleTable;

            this.CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateSqlForSingleSchemaTwoTablesWithForeignKey()
        {
            ParsedInput parsedInput;
            var generator = this.GetGenerator(out parsedInput, SampleSchema.SingleSchemaTwoTables);
            
            var actual = Database.GenerateSchemaScripts(SchemaOutputType.Create, null, parsedInput, generator);
            var expected = ExpectedResults.MarkupSingleSchemaTwoTablesWithForeignKey;

            this.CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateSqlForLookupData()
        {
            ParsedInput parsedInput;
            var generator = this.GetGenerator(out parsedInput, SampleSchema.MultiSchemaMultiTable, SampleData.LookupData);

            var actual = Database.GenerateDataScripts(parsedInput, generator).Single().Value;
            var expected = ExpectedResults.Data_LookupData;

            this.CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateSqlForFakeDataDbo()
        {
            ParsedInput parsedInput;
            var generator = this.GetGenerator(out parsedInput, SampleSchema.MultiSchemaMultiTable, SampleData.FakeData_dbo);

            var actual = Database.GenerateDataScripts(parsedInput, generator).Single().Value;
            var expected = ExpectedResults.Data_FakeData_dbo;

            this.CompareLines(expected, actual);
        }

        [TestMethod]
        public void GenerateSqlForFakeData()
        {
            ParsedInput parsedInput;
            var dataInput = DataInputBuilder
                .With("lookup", SampleData.LookupData)
                .With("seed", SampleData.SeedData)
                .With("fake", SampleData.FakeData_store, SampleData.FakeData_dbo);

            var generator = this.GetGenerator(out parsedInput, SampleSchema.MultiSchemaMultiTable, dataInput.ToDictionary());

            var actual = Database.GenerateDataScripts(parsedInput, generator)["fake"];
            var expected = ExpectedResults.Data_FakeData;

            this.CompareLines(expected, actual);
        }
    }
}